Downloads a Spotify playlist as MP3 files with proper ID3 tags (title, artist, album, year, track number, genre).
- Ruby 3.3+
- yt-dlp —
brew install yt-dlp - Python 3 + mutagen —
pip3 install mutagen - A Spotify Developer application
- Para playlists ou vídeos únicos do YouTube/YouTube Music não é necessária nenhuma credencial adicional — só o
yt-dlp.
- Crie um app em developer.spotify.com.
- Adicione
http://127.0.0.1:8888/callbackcomo Redirect URI nas configurações do app. - Instale as dependências:
make installIsso verifica a versão do Ruby, instala o yt-dlp (via Homebrew no macOS ou apt no Linux), instala o mutagen (Python) e roda bundle install. Cada etapa pode ser rodada isoladamente (make check-ruby, make install-yt-dlp, make install-mutagen, make bundle) — veja make help para a lista completa. Se preferir instalar manualmente, veja a seção Requirements acima.
- Execute o setup interativo:
bin/exportify init=== Exportify Setup ===
Diretório principal [musics]: ~/Music
Spotify Client ID: <seu client id>
Spotify Client Secret: ████████
Configuração salva em ~/.exportify
As credenciais e o diretório ficam salvos em ~/.exportify (permissão 600). Para reconfigurar qualquer campo, execute init novamente — Enter em branco mantém o valor atual.
Alternativa: as variáveis de ambiente
SPOTIFY_CLIENT_IDeSPOTIFY_CLIENT_SECRETtêm prioridade sobre o arquivo de configuração, útil em ambientes de CI.
bin/exportify https://open.spotify.com/playlist/<playlist_id>Os arquivos são organizados em subdiretórios pelo nome da playlist:
musics/
Rock dos Anos 80/
Queen - Bohemian Rhapsody.mp3
David Bowie - Heroes.mp3
Trap Brasil/
...
Faixas que já existem no disco são ignoradas automaticamente. Rodar o comando novamente após adicionar músicas à playlist baixa apenas as novas.
exportify https://www.youtube.com/playlist?list=<id>
exportify https://music.youtube.com/playlist?list=<id>Para playlists privadas, use --browser para reaproveitar os cookies de um navegador logado no YouTube:
exportify https://www.youtube.com/playlist?list=<id> --browser=chromeQuando o vídeo tem metadado oficial (YouTube Music / Content ID), artista, álbum e ano são extraídos diretamente; caso contrário, o artista é extraído do padrão "Artista - Título" no título do vídeo (com fallback para o nome do canal), e o nome da playlist é usado como álbum. O campo gênero sempre fica em branco (o YouTube não expõe esse dado). As flags --retag e --sync funcionam da mesma forma que para playlists do Spotify.
Nota: para obter esses metadados completos, a busca da playlist não usa mais o modo "flat" do yt-dlp, o que torna a listagem de playlists grandes (centenas de faixas) mais lenta — o yt-dlp precisa resolver os metadados de cada vídeo antes de começar a baixar.
exportify "https://www.youtube.com/watch?v=<id>"Se o vídeo tiver capítulos declarados (comum em mixes e compilações, onde cada capítulo marca o início de uma música), o exportify baixa o vídeo uma única vez e separa automaticamente em um MP3 por capítulo, com artista extraído do título do capítulo (padrão "Artista - Título", com fallback para o canal) e álbum = título do vídeo. Sem capítulos, baixa como uma faixa única. As flags --retag, --sync e --browser funcionam da mesma forma que para playlists.
Para remover do disco as músicas que foram retiradas da playlist:
bin/exportify https://open.spotify.com/playlist/<playlist_id> --syncPara atualizar as tags dos arquivos já baixados sem rebaixar:
bin/exportify https://open.spotify.com/playlist/<playlist_id> --retagPara navegar pelas playlists e músicas já baixadas em um painel web:
bin/exportify webAbre um servidor local em http://localhost:4567 com a lista de playlists,
as faixas de cada uma e os detalhes (tags ID3, duração, tamanho) com player
de áudio. Para usar outra porta:
bin/exportify web --port 8080App somente leitura — os downloads continuam sendo feitos via CLI (
bin/exportify <url>).
bundle exec rake test # testes
bundle exec rubocop # lint
bundle exec bundler-audit check --update # vulnerabilidades em dependênciasO CI roda os três automaticamente a cada push.
Para publicar uma nova versão no RubyGems:
- Atualize
lib/exportify/version.rb - Crie e faça push da tag:
git tag v1.0.0
git push --tagsO workflow de release dispara automaticamente e publica a gem. Requer o secret RUBYGEMS_API_KEY configurado em Settings → Secrets → Actions do repositório.
Veja o CHANGELOG.md para o histórico de versões.
- O token OAuth é cacheado em
~/.exportify_token.jsone renovado automaticamente quando expira. Se a sessão for revogada, o arquivo é removido e um novo login é solicitado. - Playlists de artistas oficiais ou gravadoras podem retornar erro 403 — isso é uma restrição da API do Spotify para apps de terceiros sem acesso estendido.
- A dependência
webrick(usada só para o servidor local de callback OAuth do login com Spotify) tem uma vulnerabilidade conhecida sem patch disponível ainda (CVE-2026-38969, request smuggling). O risco prático é baixo aqui: o servidor roda só em127.0.0.1, atende uma única requisição do próprio navegador do usuário durante o login, e não fica atrás de nenhum proxy — não há a cadeia proxy→backend que esse tipo de ataque explora. Reavaliar quando uma versão corrigida dowebrickfor lançada.